/*  ----------------------------------------------------------------------------
 *  Arello Mobile
 *  Fast 3d Engine
 *  ----------------------------------------------------------------------------
 * Except where otherwise noted, this work is licensed under
 * http://creativecommons.org/licenses/by/3.0
 */

#include "RenderTarget.h"
#include "Hardware.h"
#include <Gluck.h>

namespace liba
{
namespace lib3d
{
namespace hard
{
namespace directx8
{

/*D3DTRANSFORMSTATETYPE RenderTarget::transform_mapper[8] =
{
	D3DTS_TEXTURE0, D3DTS_TEXTURE1,
	D3DTS_TEXTURE2, D3DTS_TEXTURE3,
	D3DTS_TEXTURE4, D3DTS_TEXTURE5,
	D3DTS_TEXTURE6, D3DTS_TEXTURE7
};*/

RenderTarget::RenderTarget(Hardware * hardware, const Atom & name, int width, int height)
:	hard::RenderTarget(name),
	hard::TextureBase(1, pictureformat::A8R8G8B8, width, height ),
	Dependent( hardware ),
	texture( 0 ),
	valid_flag( false )
{
}

RenderTarget::~RenderTarget()
{
	hardware->remove_render_target( this );
	release();
}

bool RenderTarget::start_scene(double left, double right, double top, double bottom)
{
	if( !valid_flag )
	{
		release();
		HRESULT hr = hardware->get_device()->CreateTexture( width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture, 0 );
		if( !texture )
			throw Gluck(__FUNCTION__, "hardware->get_device()->CreateTexture() failed");

///		hr = hardware->get_device()->CreateOffscreenPlainSurface( width, height, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &offscreen_surface, 0 );
///		if( !offscreen_surface )
///			throw Gluck(__FUNCTION__, "hardware->get_device()->CreateOffscreenPlainSurface() failed");
		
		valid_flag = true;
	}
	IDirect3DSurface9 * surface = 0;
	HRESULT hr = texture->GetSurfaceLevel( 0, &surface );
	if( !surface )
		throw Gluck(__FUNCTION__, "texture->GetSurfaceLevel() failed");
	hr = hardware->get_device()->SetRenderTarget( 0, surface );
	surface->Release();

	hr = hardware->get_device()->BeginScene();
	if( FAILED( hr ) )
		return false;

	int le = width*(1+left)/2;
	int ri = width*(1+right)/2;
	int to = height*(1-top)/2;
	int bo = height*(1-bottom)/2;
	hardware->set_params_for_start_scene(le, ri, to, bo);
	return true;
}

const int RenderTarget::get_width()const
{
	return width;
}

const int RenderTarget::get_height()const
{
	return height;
}

bool RenderTarget::is_valid()
{
	return true;
}

bool RenderTarget::set_in_hardware(int stage)
{
///	if( hardware->test_and_set_last_texture(stage, this) )
///		return true;
	hardware->get_device()->SetTexture( stage, texture );

//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_TEXCOORDINDEX, stage );
//	hardware->get_device()->SetTransform( transform_mapper[stage], &hardware->get_identity_matrix() );

//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_COLORARG1, D3DTA_TEXTURE );
//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_COLORARG2, D3DTA_CURRENT );
//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_COLOROP,   D3DTOP_MODULATE );
//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT );
//	hardware->get_device()->SetTextureStageState( stage, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
	return true;
}

void RenderTarget::get_data()
{
/*	IDirect3DSurface9 * surface = 0;
	HRESULT hr = texture->GetSurfaceLevel( 0, &surface );
	if( !surface )
		throw Gluck(__FUNCTION__, "texture->GetSurfaceLevel() failed");
	hr = hardware->get_device()->GetRenderTargetData(surface, offscreen_surface);
	surface->Release();*/
}

void RenderTarget::invalidate()
{
//	valid_flag = false;
	release();
}

void RenderTarget::release()
{
	valid_flag = false;

	if( texture )
		texture->Release();
	texture = 0;
///	if( offscreen_surface )
///		offscreen_surface->Release();
///	offscreen_surface = 0;
}

} // namespace directx8
} // namespace hard
} // namespace lib3d
} // namespace liba

